﻿using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using Microsoft.WindowsAzure.Storage.Table.DataServices;
using POC.Azure.Storage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace Quiz.Model.Data
{
    public interface IQuizRepository<T>
    {
        T Find(Expression<Func<T, bool>> predicate);
        IEnumerable<T> Query(Expression<Func<T, bool>> predicate);
        void Add(T entityToAdd);
        void Update(T entityToUpdate);
        void Delete(T entityToDelete);
        IQueryable<T> Load();
    }
    public class QuizRepository<T> : QuizSetDataContext, IQuizRepository<T>
    {
        CloudTableClient _tableClient;
        private string _entitySetName;

        public QuizSetDataContext Context { get; set; }

        public static QuizRepository<T> Create(AzureAccount account)
        {
            QuizRepository<T> context = new QuizRepository<T>(account.CloudAccount.CreateCloudTableClient());
            return context;
        }
        public QuizRepository(CloudTableClient tableAccount)
            : base(tableAccount)
        {
            Context = this;
            _tableClient = tableAccount;
            _entitySetName = typeof(T).Name;
           // _tableClient.GetTableReference(_entitySetName).CreateIfNotExists();
        }
        public T Find(Expression<Func<T, bool>> predicate)
        {
           var entity = Load().Where(predicate).FirstOrDefault();
           return entity;
        }
        public IEnumerable<T> Query(Expression<Func<T, bool>> predicate)
        {
            var list = Load().Where(predicate).ToList();
            return list;
        }
        public void Add(T entityToAdd)
        {
            AddObject(_entitySetName, entityToAdd);
            SaveChanges();
        }

        public void Update(T entityToUpdate)
        {
            UpdateObject(entityToUpdate);
            SaveChanges();
        }

        public void Delete(T entityToDelete)
        {
            DeleteObject(entityToDelete);
            SaveChanges();
        }

        public IQueryable<T> Load()
        {
            return CreateQuery<T>(_entitySetName);
        }
        
    }
    public class Query<T> : TableServiceQuery<T> where T : TableServiceEntity
    {
        private string _entitySetName;
        public string EntitySetName
        {
            get { return _entitySetName; }
            set { _entitySetName = value; }
        }
        public Query(IQueryable<T> query, TableServiceContext context)
            : base(query, context)
        {
            _entitySetName = typeof(T).Name;
        }
    }
}
